
#include "stdafx.h"

#include "childframeweb.h"
#include "displayfrm.h"
#include "displayhelper.h"

#include "webcore/webcore.h"
#include "data/bookfavorite.h"

UINT WM_SNB_VIEWCREATED		= RegisterWindowMessage(_T("WM_SNB_CREATEVIEW"));
UINT WM_SNB_GETCONTAINER	= RegisterWindowMessage(_T("WM_SNB_GETCONTAINER"));

DWORD WINAPI _threadSnbCreateView(LPVOID lpData)
{
	HWND hChildFrame = (HWND)lpData;

	::OleInitialize(NULL);
	
	CSnbAdapterCreator AdapterCreator;
	CWebContainer *pWebContainer = new CWebContainer(&AdapterCreator);

	CClientRect rcClient(hChildFrame);
	pWebContainer->Create(hChildFrame, rcClient);	
	pWebContainer->CreateWebControl();

	::PostMessage(hChildFrame, WM_SNB_VIEWCREATED, 0, (LPARAM)pWebContainer->m_hWnd);

	MSG msg;
	while (::GetMessage(&msg, NULL, 0, 0))
	{
		::TranslateMessage(&msg);
		::DispatchMessage(&msg);
	}

	::OleUninitialize();

	return 0;
}

//////////////////////////////////////////////////////////////////////////
// helper 

//////////////////////////////////////////////////////////////////////////
// CSnbExternalDispatchAdapter

CSnbExternalDispatchAdapter::CSnbExternalDispatchAdapter(CWebContainer* pWebContainer)
: CExternalDispatch(pWebContainer)
{
}

CSnbExternalDispatchAdapter::~CSnbExternalDispatchAdapter()
{
}

STDMETHODIMP CSnbExternalDispatchAdapter::GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
{
	return E_NOTIMPL;
}

STDMETHODIMP CSnbExternalDispatchAdapter::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
	return E_NOTIMPL ; 
}


//////////////////////////////////////////////////////////////////////////
// CSnbInternetSecurityManagerAdapter
CSnbInternetSecurityManagerAdapter::CSnbInternetSecurityManagerAdapter(CWebContainer* pWebContainer)
: CInternetSecurityManager(pWebContainer)
{
}

CSnbInternetSecurityManagerAdapter::~CSnbInternetSecurityManagerAdapter()
{
}

STDMETHODIMP CSnbInternetSecurityManagerAdapter::MapUrlToZone(LPCWSTR pwszUrl, DWORD *pdwZone, DWORD dwFlags)
{
	*pdwZone = 3;
	return S_OK;
}

STDMETHODIMP CSnbInternetSecurityManagerAdapter::ProcessUrlAction(LPCWSTR pwszUrl, DWORD dwAction, BYTE *pPolicy, DWORD cbPolicy, BYTE *pContext, DWORD cbContext, DWORD dwFlags, DWORD dwReserved)
{
	*pPolicy = URLPOLICY_ALLOW;
	return S_OK;
}


//////////////////////////////////////////////////////////////////////////
// CSnbCustomSiteAdapter

CSnbCustomSiteAdapter::CSnbCustomSiteAdapter(CWebContainer* pWebContainer)
: CCustomSite(pWebContainer)
{
	m_pExternalDispatch = new CSnbExternalDispatchAdapter(pWebContainer);
	m_pExternalDispatch->AddRef();
}

CSnbCustomSiteAdapter::~CSnbCustomSiteAdapter()
{
	if (m_pExternalDispatch != NULL)
	{
		m_pExternalDispatch->Release();
		m_pExternalDispatch = NULL;
	}
}

STDMETHODIMP CSnbCustomSiteAdapter::GetExternal(IDispatch **ppDispatch)
{
	if (m_pExternalDispatch)
	{
		m_pExternalDispatch->AddRef() ;
		*ppDispatch = m_pExternalDispatch;

		return S_OK ;
	}

	return E_NOTIMPL ;
}

STDMETHODIMP CSnbCustomSiteAdapter::QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
{
	if (!ppvObject)
		return E_POINTER;

	if (guidService == SID_SInternetSecurityManager)
	{
		CSnbInternetSecurityManagerAdapter* pAdapter = new CSnbInternetSecurityManagerAdapter(m_pWebContainer);
		return pAdapter->QueryInterface(riid, ppvObject);
	}

	*ppvObject = NULL;

	return E_NOINTERFACE;
}

STDMETHODIMP CSnbCustomSiteAdapter::ShowMessage(HWND hwnd, LPOLESTR lpstrText, LPOLESTR lpstrCaption, DWORD dwType, LPOLESTR lpstrHelpFile, DWORD dwHelpContext, LRESULT *plResult)
{
	USES_CONVERSION_EX;
	CResString<MAX_PATH> strTitle(IDS_APP_TITLE);

	*plResult = ::MessageBox(hwnd, OLE2T_EX(lpstrText, 0), strTitle, dwType);

	return S_OK;
}


//////////////////////////////////////////////////////////////////////////
// CSnbWebEventSinkAdapter

CSnbWebEventSinkAdapter::CSnbWebEventSinkAdapter(CWebContainer* pWebContainer)
: CWebEventSink(pWebContainer)
{
}

CSnbWebEventSinkAdapter::~CSnbWebEventSinkAdapter()
{
}

HRESULT CSnbWebEventSinkAdapter::OnTitleChange(REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
{
	if (pDispParams->cArgs < 1)
		return E_FAIL ;

	CComBSTR bstrTitle(pDispParams->rgvarg[0].bstrVal);
	LPCTSTR lpszTitle = OLE2T_EX(bstrTitle, 0);
	::SendMessage(m_pWebContainer->GetParent(), WM_SETTEXT, 0, (LPARAM)lpszTitle);

	return S_OK ;
}

HRESULT CSnbWebEventSinkAdapter::OnNewWindow2(REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
{
	return S_FALSE;
}

HRESULT CSnbWebEventSinkAdapter::OnNewWindow3(REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
{
	VARIANT_BOOL *&Cancel = pDispParams->rgvarg[3].pboolVal;
	IDispatch **&ppDisp = pDispParams->rgvarg[4].ppdispVal;

	USES_CONVERSION_EX;
	CreatePageData* pData = CreatePageData::Init(OLE2T_EX(pDispParams->rgvarg[0].bstrVal, 0));

	HWND hMainWnd = GetAncestor(m_pWebContainer->m_hWnd, GA_ROOTOWNER);
	HWND hChildFrame = CreatePageData::SendMessageCreatePage(hMainWnd, pData);
	CreatePageData::Release(pData);

	if (hChildFrame == NULL)
	{
		*Cancel = VARIANT_TRUE;
		return S_OK;
	}

	HWND hWebContainer = NULL ;
	for (int i = 0; i < 1000; ++i)
	{
		hWebContainer = (HWND)SendMessage(hChildFrame, WM_SNB_GETCONTAINER, 0, 0);
		if (hWebContainer)
			break;

		Sleep(10);
	}

	if (hWebContainer == NULL)
	{
		*Cancel = VARIANT_TRUE;
		return S_OK;
	}


	COPYDATASTRUCT cds = { (ULONG_PTR)hWebContainer, 0, NULL };
	DWORD dwResult = 0;
	
	SendMessageTimeout(hWebContainer, WM_COPYDATA, 0, (LPARAM)&cds, SMTO_BLOCK | SMTO_NOTIMEOUTIFNOTHUNG, 0, &dwResult);
	if (dwResult != 0)
	{
		LPSTREAM lpStream = (LPSTREAM)dwResult;
		
		CComPtr<IWebBrowser2> spWebBrowser;
		if (SUCCEEDED(CoGetInterfaceAndReleaseStream(lpStream, IID_IWebBrowser2, (void**)&spWebBrowser)) && spWebBrowser != NULL)
		{	
//#ifndef _DEBUG
			spWebBrowser->put_RegisterAsBrowser(VARIANT_FALSE);
			spWebBrowser->put_RegisterAsDropTarget(VARIANT_FALSE);
//#endif

			if (SUCCEEDED(spWebBrowser->get_Application(ppDisp)) && ppDisp)
				return S_OK;
		}
	}

	*Cancel = VARIANT_TRUE;
	return S_OK;
}

HRESULT CSnbWebEventSinkAdapter::OnBeforeNavigate2(REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
{
	return S_OK;
}

HRESULT CSnbWebEventSinkAdapter::OnNavigateError(REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
{
/*
	CComBSTR bstrUrl = pDispParams->rgvarg[3].pvarVal->bstrVal;
	IDispatch* pDispatch = pDispParams->rgvarg[4].pdispVal;
	if (pDispatch == NULL) return S_OK;

	CComPtr<IWebBrowser2> spWebBrowser2;
	HRESULT hr = pDispatch->QueryInterface(IID_IWebBrowser2, (void**)&spWebBrowser2);
	if (SUCCEEDED(hr) && spWebBrowser2)
	{
		CComPtr<IDispatch> spDispDoc;
		hr = spWebBrowser2->get_Document(&spDispDoc);
		if (SUCCEEDED(hr) && spDispDoc)
		{
			CComPtr<IHTMLDocument2> spHTMLDocument2;
			hr = spDispDoc->QueryInterface(IID_IHTMLDocument2, (void**)&spHTMLDocument2);
			if (SUCCEEDED(hr) && spHTMLDocument2)
			{
				USES_CONVERSION_EX;

				CString strContent = _T("error");

				SAFEARRAY *psaStrings = SafeArrayCreateVector(VT_VARIANT, 0, 1);
				VARIANT *param;
				HRESULT hr = SafeArrayAccessData(psaStrings, (LPVOID*)&param);
				param->vt = VT_BSTR;
				param->bstrVal = ::SysAllocString(T2W_EX((LPTSTR)(LPCTSTR)strContent, 0));

				hr = SafeArrayUnaccessData(psaStrings);
				hr = spHTMLDocument2->write(psaStrings);
				if (psaStrings != NULL) 
					SafeArrayDestroy(psaStrings);

				*pDispParams->rgvarg[0].pboolVal = VARIANT_TRUE;
			}
		}
	}
*/
	return S_OK ;
}


// BOOL CSnbWebEventSinkAdapter::IsLocalSnbFile(LPCTSTR lpszUrl)
// {
// 	CString strUrl = lpszUrl;
// 
// 	TCHAR szScheme[] = _T("file:///");	
// 
// 	if (strUrl.GetLength() < 14)
// 		return false;
// 
// 	if (strUrl.Mid(0, 8).CompareNoCase(szScheme) != 0)
// 		return false;
// 
// 	strUrl = strUrl.Mid(8);
// 	if (!isalpha(strUrl[0]) || strUrl[1] != ':')
// 		return false;
// 
// 	if (strUrl.Right(4).CompareNoCase(_T(".snb")) != 0)
// 		return false;
// 
// 	return true;
// }

///////////////////////////////////////////////////////////////////////////
// CSnbWebControlExAdapter

CSnbWebControlExAdapter::CSnbWebControlExAdapter(CWebContainer* pWebContainer)
: CWebControlEx(pWebContainer)
{
}

CSnbWebControlExAdapter::~CSnbWebControlExAdapter()
{
}
